function gewQueryItem()
{
  this.type = 0;
  this.xhr = null;
  this.texture = null;
  this.name = null;
  this.url = null;
  this.status = GEW_DOWNLOAD_STATUS_WAITING;
}
gewQueryItem.prototype =
{
  start:function()
  {
    this.status = GEW_DOWNLOAD_STATUS_RUNNING;
    if(this.xhr)
    {
      this.xhr.send();
    }
    else if(this.type = GEW_RESOURCE_TEXTURE)
    {
      var img = new Image();
      var queryItem = this;
      img.gewTexture = this.texture;
      img.onload = function()
      {
        //alert("LOADED!");
        queryItem.status = GEW_DOWNLOAD_STATUS_FINISHED;
        this.gewTexture.loadIntoGLMemory(img);
        delete img;
      }
      img.onerror = function()
      {
        alert("Error when trying loading image from url :"+img.src);
        delete img;
      }
      img.src = this.url; 
    }
  }
}
function gewResourceManager(game)
{
  this.game= game;
  this.textureManager = new gewTextureManager(game);
  this.meshManager = new gewMeshManager(game);
  this.floatMaps = {};
  this.blockQuery = [];
  this.nonblockQuery = [];
  this.maxRunningItem = 6;
  this.currentRunningCount = 0;
  this.isBlocking = false;
  // callback function
  this.startBlockCallback = function(){ /*console.log("Blocking")*/};
  this.endBlockCallback = function(){} 
  this.finishDownloadItemCallback = function(item){};
  this.startDownloadItemCallback = function(item){};
}

gewResourceManager.prototype =
{
  getMesh:function(name)
  {
    return this.meshManager.getMesh(name);
  },
  getTexture:function(name)
  {
    return this.textureManager.getTexture(name);
  },
  getAtlas:function(name)
  {
    return this.textureManager.getAtlas(name);
  },
  getFloatMap:function(name)
  {
    return this.floatMaps[name];
  },
  removeFloatmap:function(name)
  {
    delete this.floatMaps[name];
  },
  removeTexture:function(name)
  {
    return this.textureManager.removeTexture(name);
  },
  removeMesh:function(name)
  {
    return this.meshManager.removeMesh(name);
  },
  ///////////////////////////////////////////////////////////////////
  // For Texture:
  //    param1 : format
  //    param2 : texture param
  //    param3 : isGenerateMipmap
  //    param4 : isFlipY
  //    param5 : isPremultiAlpha
  // For Mesh:
  //    param1 : is auto create VBO
  // For Texture atlas
  //    param1 : main texture list (array)
  // For Float map
  //    param1 : mipmap level num   
  // For SceneGraph JSON 
  //    param1 : scene3d
  //    param2 : physicEngine 
  load: function(name,url,isBlockGame,isShouldCache,param1,param2,param3,param4,param5)
  {
    // Check if this url is already in query
    var bQuery = this.blockQuery;
    var nQuery = this.nonblockQuery;
    var bLen = bQuery.length;
    var nLen = nQuery.length;
    for(var i=0;i<bLen;i++)
    {
      var item = bQuery[i];
      if( item.url==url)
        return;
    }
    for(var i=0;i<nLen;i++)
    {
      var item = nQuery[i];
      if( item.url==url)
      {
        if(item.status== GEW_DOWNLOAD_STATUS_FINISHED||item.status==GEW_DOWNLOAD_STATUS_RUNNING)
          return;
        else if(isBlockGame) // Move this item to block query
        {
          bQuery.push(item);
          nQuery.splice(i,1);
        }
      }  
    }
    
    // get extension of url
    var urlLen = url.length;
    var urlExt = null;
    for(var i=urlLen-1;i>0;i--)
    {
      if(url[i]=='.')
      {
        urlExt = url.substring(i+1,urlLen);
      }
    }
    if(!urlExt)
    {
      alert("gewResourceManager:load:Error!, this url "+url+" don't have extension")
      return false;  
    }
      
    var queryItem = new gewQueryItem();
    queryItem.url = url;
    queryItem.name = name;
    var mManager = this.meshManager;
    var tManager = this.textureManager;
    ////////////////////////////////////////////////
    // MESH
    if(urlExt=="obj")
    {
      // Check is name exist
      var testName = mManager.getMesh(name);
      if(testName)
      {
        alert("gewResourceManager:load:Error! this mesh name '"+name+"' already in used!( url ="+url+")");
        return false;
      }
      queryItem.type = GEW_RESOURCE_MESH;
      queryItem.xhr = mManager.createObjRequest(name,url,param1,queryItem);
    }
    if(urlExt=="ism1")
    {
      // Check is name exist
      var testName = mManager.getMesh(name);
      if(testName)
      {
        alert("gewResourceManager:load:Error! this mesh name '"+name+"' already in used!( url ="+url+")");
        return false;
      }
      queryItem.type = GEW_RESOURCE_MESH;
      queryItem.xhr = mManager.createISM1Request(name,url,param1,queryItem);
    }
    if(urlExt=="kam1")
    {
      // Check is name exist
      var testName = mManager.getMesh(name);
      if(testName)
      {
        alert("gewResourceManager:load:Error! this mesh name '"+name+"' already in used!( url ="+url+")");
        return false;
      }
      queryItem.type = GEW_RESOURCE_MESH;
      queryItem.xhr = mManager.createKAM1Request(name,url,param1,queryItem);
    }
    if(urlExt=="sam1")
    {
      // Check is name exist
      var testName = mManager.getMesh(name);
      if(testName)
      {
        alert("gewResourceManager:load:Error! this mesh name '"+name+"' already in used!( url ="+url+")");
        return false;
      }
      queryItem.type = GEW_RESOURCE_MESH;
      queryItem.xhr = mManager.createSAM1Request(name,url,param1,queryItem);
    }
    //////////////////////////////////////////////////////
    // Download TEXTURE
    if(urlExt=="jpg" || urlExt=="png" || urlExt=="bmp")
    {
      var testName = tManager.getTexture(name);
      if(testName)
      {
        alert("gewResourceManager:load:Error! this name '"+name+"' already in used!( url ="+url+")");
        return false;
      }
      queryItem.type = GEW_RESOURCE_TEXTURE;
      queryItem.texture = tManager.loadTexture(name, url, param1, param2,param3,param4,param5);
    }
    // Download Float-map
    if(urlExt=="fm")
    {
      var testName = this.getFloatMap(name);
      if(testName)
      {
        alert("gewResourceManager:load:Error! this name '"+name+"' already in used!( url ="+url+")");
        return false;
      }
      queryItem.type = GEW_RESOURCE_FLOAT_MAP;
      this.floatMaps[name] = new gewFloatMap(url,param1,queryItem);
    }    
    // Download Texture_atlas
    if(urlExt=="tai")
    {
      var testName = tManager.getAtlas(name);
      if(testName)
      {
        alert("gewResourceManager:load:Error! this name '"+name+"' already in used!( url ="+url+")");
        return false;
      }
      queryItem.type = GEW_RESOURCE_ATLAS_DECS;
      queryItem.xhr = tManager.createTextureAtlasRequest(name, url, param1,queryItem);
    }
    //////////////////////////////////////////////
    // Download SceneGraph JSON
    if(urlExt=="gsg")
    {
      queryItem.type = GEW_RESOURCE_SCENEGRAPH_JSON;
      queryItem.xhr = param1.createScenegraphJSONRequest(url,param2,queryItem);
    }
    if(isBlockGame)
    {
      this.blockQuery.push(queryItem);
    }
    else
    {
      this.nonblockQuery.push(queryItem);
    }
  },
  updateQuery:function(query,isBlockQuery)
  {
    var len = query.length;
    for(var i=0;i<len;i++)
    {
      var item = query[i];
      /*
      if(item.status== GEW_DOWNLOAD_STATUS_RUNNING)
      {
        // Check this item is finished or not
        var type = item.type;
        var isFinished = false;
        if(type==GEW_RESOURCE_MESH)
        {
          var mesh = this.meshManager.getMesh(item.name);
          if(mesh)
            isFinished = mesh.isReady;         
        }
        else if(type==GEW_RESOURCE_TEXTURE)
        {
          var tex = this.textureManager.getTexture(item.name);
          if(tex)
            isFinished = tex.isReady;    
        }
        else if(type==GEW_RESOURCE_ATLAS_DECS)
        {
          var atlas = this.textureManager.getAtlas(item.name);
          isFinished = atlas.isReady;
        }
        else if(type==GEW_RESOURCE_FLOAT_MAP)
        {
          var floatMap = this.getFloatMap(item.name);
          isFinished = floatMap.isReady;
        }
        
        if(isFinished)
        {
          item.status = GEW_DOWNLOAD_STATUS_FINISHED;
          this.currentRunningCount--;
        }
      }
      else*/
      if(item.status== GEW_DOWNLOAD_STATUS_FINISHED)
      {
        this.currentRunningCount--;
        this.finishDownloadItemCallback(item);
        delete query[i];
        query.splice(i,1);
        i--;len--;
      }
      else if(item.status==GEW_DOWNLOAD_STATUS_WAITING)
      {
        if(this.currentRunningCount<this.maxRunningItem)
        {
          if(isBlockQuery)
          {
            item.start();
            this.startDownloadItemCallback(item);
            this.currentRunningCount++;
          }
          else
          {
            var bLen = this.blockQuery.length;
            if(bLen==0)
            {
              item.start();
              this.startDownloadItemCallback(item);
              this.currentRunningCount++;
            }
            else
              return;
          }
        }
        else
          return;
      }
    }
  },
  onTick:function(mls)
  {
    var bQuery = this.blockQuery;
    var nQuery = this.nonblockQuery;
    var bLen = bQuery.length;
    var nLen = nQuery.length;
    if (bLen > 0) {
      if(!this.isBlocking)
        this.startBlockCallback();
      this.isBlocking = true;
    }
    else {
      if (this.isBlocking) 
        this.endBlockCallback();
      this.isBlocking = false;
    }
    this.updateQuery(bQuery,true);
    this.updateQuery(nQuery,false);
    return this.isBlocking;    
  }
}

